#include "mainwindow.h"
#include "ui_mainwindow.h"

void getHTTPString(const QByteArray &strs)
{
    qDebug() << "strs:" << QString(strs);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::get(const QString &apiPath, std::function<void (const QByteArray &)> callback, const int msec, const QString &contentType)
{
    if (apiPath.isEmpty())
   {
       return;
   }
   QNetworkAccessManager *netManager = new QNetworkAccessManager;
   QNetworkRequest netRequest;
   if (!contentType.isEmpty())
   {
       netRequest.setHeader(QNetworkRequest::ContentTypeHeader,contentType);
   }

   netRequest.setUrl(QUrl(apiPath));
   QNetworkReply *reply = netManager ->get(netRequest);
   QTimer *timer = new QTimer(this);
   timer->start(msec);
   connect(timer, &QTimer::timeout, [=](){
       qDebug() << "time out";
       if (reply)
       {
           reply->abort();
       }
   });
   connect(reply, &QNetworkReply::finished, [=](){
       timer->stop();
       if (reply->error() == QNetworkReply::NoError)
       {
           ui->textEdit->append(reply->readAll());
//           qDebug() << "NoError=" << reply->readAll();
           callback(reply->readAll());
       }
       else
       {
           ui->textEdit->append("error=" + QString::number((int)reply->error()));
//           qDebug() << "error=" << reply->error();
       }
//       qDebug() << "request finished";
   });
   return;
}

void MainWindow::getSync(const QString &apiPath, std::function<void (const QByteArray &)> prcDataFn, const int msec, const QString &contentType)
{
    QNetworkAccessManager *netManager = new QNetworkAccessManager;
    if (apiPath.isEmpty())
    {
        return;
    }
    QNetworkRequest netRequest;
    if (!contentType.isEmpty())
    {
        netRequest.setHeader(QNetworkRequest::ContentTypeHeader,contentType);
    }
    netRequest.setUrl(QUrl(apiPath));
    QNetworkReply *reply = netManager->get(netRequest);
    QTimer *timer = new QTimer(this);
    QEventLoop *loop = new QEventLoop(this);
    timer->start(msec);
    connect(timer, &QTimer::timeout, [=](){
        qDebug() << "time out";
        reply->abort();
    });
    connect(reply, &QNetworkReply::finished, [=](){
        timer->stop();
        loop->quit();
        loop->deleteLater();
    });
    loop->exec();
    if (reply->error() == QNetworkReply::NoError)
    {
        ui->textEdit->append(reply->readAll());
//        qDebug() << "read data";
        prcDataFn(reply->readAll());
    }
    else
    {
        ui->textEdit->append("error=" + QString::number((int)reply->error()));
//        qDebug() << "error=" << reply->error();
    }
    return;
}

void MainWindow::post(const QString &apiPath, std::function<void (const QByteArray &)> callback, const int msec, const QString &contentType)
{
    if (apiPath.isEmpty())
   {
       return;
   }
   QNetworkAccessManager *netManager = new QNetworkAccessManager;
   QNetworkRequest netRequest;
   if (!contentType.isEmpty())
   {
       netRequest.setHeader(QNetworkRequest::ContentTypeHeader,contentType);
   }

   netRequest.setUrl(QUrl(apiPath));
   QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

   QNetworkReply *reply = netManager->post(netRequest, multiPart);
   QTimer *timer = new QTimer(this);
   timer->start(msec);
   connect(timer, &QTimer::timeout, [=](){
       qDebug() << "time out";
       if (reply)
       {
           reply->abort();
       }
   });
   connect(reply, &QNetworkReply::finished, [=](){
       timer->stop();
       if (reply->error() == QNetworkReply::NoError)
       {
           ui->textEdit->append(reply->readAll());
//           qDebug() << "NoError=" << reply->readAll();
           callback(reply->readAll());
       }
       else
       {
           ui->textEdit->append("error=" + QString::number((int)reply->error()));
//           qDebug() << "error=" << reply->error();
       }
//       qDebug() << "request finished";
   });
   return;
}

void MainWindow::postSync(const QString &apiPath, std::function<void (const QByteArray &)> prcDataFn, const int msec, const QString &contentType)
{
    QNetworkAccessManager *netManager = new QNetworkAccessManager;
    if (apiPath.isEmpty())
    {
        return;
    }
    QNetworkRequest netRequest;
    if (!contentType.isEmpty())
    {
        netRequest.setHeader(QNetworkRequest::ContentTypeHeader,contentType);
    }
    netRequest.setUrl(QUrl(apiPath));

    QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    QNetworkReply *reply = netManager->post(netRequest, multiPart);
    QTimer *timer = new QTimer(this);
    QEventLoop *loop = new QEventLoop(this);
    timer->start(msec);
    connect(timer, &QTimer::timeout, [=](){
        qDebug() << "time out";
        reply->abort();
    });
    connect(reply, &QNetworkReply::finished, [=](){
        timer->stop();
        loop->quit();
        loop->deleteLater();
    });
    loop->exec();
    if (reply->error() == QNetworkReply::NoError)
    {
        ui->textEdit->append(reply->readAll());
//        qDebug() << "read data";
        prcDataFn(reply->readAll());
    }
    else
    {
        ui->textEdit->append("error=" + QString::number((int)reply->error()));
//        qDebug() << "error=" << reply->error();
    }
    return;
}

void MainWindow::on_pushButton_3_clicked()
{
    ui->textEdit->append(QStringLiteral("get begin"));
    get(ui->lineEdit->text(), getHTTPString, 10000, "");
    ui->textEdit->append(QStringLiteral("get end"));
}

void MainWindow::on_pushButton_2_clicked()
{
    ui->textEdit->append(QStringLiteral("getSync begin"));
    getSync(ui->lineEdit->text(), getHTTPString, 10000, "");
    ui->textEdit->append(QStringLiteral("getSync end"));
}

void MainWindow::on_pushButton_4_clicked()
{
    ui->textEdit->append(QStringLiteral("postSync begin"));
    postSync(ui->lineEdit->text(), getHTTPString, 10000, "");
    ui->textEdit->append(QStringLiteral("postSync end"));
}

void MainWindow::on_pushButton_clicked()
{
    ui->textEdit->append(QStringLiteral("post begin"));
    post(ui->lineEdit->text(), getHTTPString, 10000, "");
    ui->textEdit->append(QStringLiteral("post end"));
}
